﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.Management.Automation.Runspaces;
using System.Management.Automation;
using System.Collections.ObjectModel;

namespace ChatRoomService
{
    // 注意: 使用“重构”菜单上的“重命名”命令，可以同时更改代码、svc 和配置文件中的类名“ChatRoomService”。
    public class ChatRoomService : IChatRoomService
    {
        public string GetChatRooms()       
        {
            var result = RunLyncPowerShell("Get-CsPersistentChatRoom", null);
            StringBuilder sb = new StringBuilder();
            foreach (PSObject psObject in result)
            {
                sb.Append(psObject.ToString());
            }

            return sb.ToString();
        }       

        public string CreatePersistentChatRoom(string adminGroupPath, string memberGroupPath, string spaceUrl,string pool, string category, string id)
        {
            string addInName = "AddIn" + id;

            string roomId = pool + "\\" + id;
            PSObject resultForCreateAddIn = this.CreateAddIn(addInName, pool, spaceUrl);
            PSObject resultForCreateChatRoom = this.CreateChatRoom(id, pool, category, addInName);
            PSObject resultForSetMemebersOfChatRoom = this.SetMemebersOfChatRoom(roomId, adminGroupPath, memberGroupPath);

            return string.Empty;
        }

        // Create addIn
        // New-CsPersistentChatAddIn -Name  "TestAddInName" -PersistentChatPoolFqdn "management.itfirst.com" -Url  "http://sharepoint2010/hz08/pages/default.aspx"
        private PSObject CreateAddIn(string addInName, string pool, string spaceUrl)
        {
            Dictionary<string, string> parameters = new Dictionary<string, string>();
            parameters.Add("Name", addInName);
            parameters.Add("PersistentChatPoolFqdn",  pool);
            parameters.Add("Url", spaceUrl);

            string command = "New-CsPersistentChatAddIn";
            return this.RunLyncPowerShell(command, parameters).First<PSObject>();
        }

        // Create new persistent chat room with created add-in
        // New-CsPersistentChatRoom -Name "ITChatRoomName" -PersistentChatPoolFqdn "management.itfirst.com" -Category "TestChatRoom001" -AddIn TestAddInName -Privacy Secret   
        private PSObject CreateChatRoom(string roomName, string pool, string category, string addIn)
        {
            Dictionary<string, string> parameters = new Dictionary<string, string>();
            parameters.Add("Name", roomName);
            parameters.Add("PersistentChatPoolFqdn", pool);
            parameters.Add("Category", category);
            parameters.Add("AddIn", addIn);

            string command = "New-CsPersistentChatRoom";
            return this.RunLyncPowerShell(command, parameters).First<PSObject>(); ;

        }

        // Set the manager group and member group for the persistent chat room
        // Set-CsPersistentChatRoom -Identity management.itfirst.com\ITChatRoom –Managers @{Add="CN=PCRoomManagersTOYIJZ0W,OU=PersistentChatGroup,DC=ITFirst,DC=com"}  –Members @{Add="CN=PCRoomMembersTOYIJZ0W,OU=PersistentChatGroup,DC=ITFirst,DC=com" }
        private PSObject SetMemebersOfChatRoom(string roomId, string managers, string members)
        {

            Dictionary<string, string> parameters = new Dictionary<string, string>();
            parameters.Add("Identity", roomId);
            //   parameters.Add("Managers", "@{Add=\"" + managers + "\"}");
            //   parameters.Add("Members", "@{Add=\"" + members + "\"}"); 
            
            parameters.Add("Managers", "" + managers + "");
            parameters.Add("Members", "" + members + "");

            string command = "Set-CsPersistentChatRoom";
            return this.RunLyncPowerShell(command, parameters).First<PSObject>();
        }

        // Remove-CsPersistentChatRoom -Identity management.itfirst.com\CC12121348 -force
        // Remove add-in: Remove-CsPersistentChatAddin -Identity management.itfirst.com\AddInCC12121348
        public void RemovePersistentChatRoom(string roomUrl)
        {
            // Remove CsPersistentChatRoom
            // Remove-CsPersistentChatRoom -Identity management.itfirst.com\6832M3TS -force -Confirm:$False
            string scriptTemplate = "Remove-CsPersistentChatRoom -Identity {0} -force -Confirm:$False";
            string script = string.Format(scriptTemplate, roomUrl);

            this.RunLyncPowerShell(script);

            // Remove CsPersistentChatAddin
            Dictionary<string, string>  parameters = new Dictionary<string, string>();
            string command = "Remove-CsPersistentChatAddin";
            string[] temp = roomUrl.Split("\\".ToCharArray());
            string identity = temp[0] + "\\" + "AddIn" + temp[1];
            parameters.Add("Identity", identity);
            this.RunLyncPowerShell(command, parameters); ;
        }

        public CompositeType GetDataUsingDataContract(CompositeType composite)
        {
            if (composite == null)
            {
                throw new ArgumentNullException("composite");
            }
            if (composite.BoolValue)
            {
                composite.StringValue += "Suffix";
            }
            return composite;
        }

        private Collection<PSObject> RunLyncPowerShell(string script)
        {
            InitialSessionState initial = InitialSessionState.CreateDefault();
            initial.ImportPSModule(new string[] { @"C:\Program Files\Common Files\Microsoft Lync Server 2013\Modules\Lync\Lync.psd1" });
            initial.AuthorizationManager = new AuthorizationManager("Lync.psd1");
            Runspace runspace = RunspaceFactory.CreateRunspace(initial);
            runspace.Open();
            Pipeline pipeline = runspace.CreatePipeline();
            pipeline.Commands.AddScript(script, true);            
            Collection<PSObject> output = pipeline.Invoke();
            string errorMessage = string.Empty;
            if (pipeline.HadErrors)
            {
                errorMessage = pipeline.Error.Read().ToString();
            }
            // pipeline.Invoke(
            runspace.Close();

            if (!string.IsNullOrWhiteSpace(errorMessage))
            {
                throw new Exception(errorMessage);
            }

            return output;
        }

        private Collection<PSObject> RunLyncPowerShell(string command, Dictionary<string, string> parameters)
        {
            InitialSessionState initial = InitialSessionState.CreateDefault();
            initial.ImportPSModule(new string[] { @"C:\Program Files\Common Files\Microsoft Lync Server 2013\Modules\Lync\Lync.psd1" });
            initial.AuthorizationManager = new AuthorizationManager("Lync.psd1");


            Runspace runspace = RunspaceFactory.CreateRunspace(initial);
            runspace.Open();

            Pipeline pipeline = runspace.CreatePipeline();
            Command psCommand = new Command(command);
            if (parameters != null && parameters.Count != 0)
            {
                Dictionary<string, string>.Enumerator enumerator = parameters.GetEnumerator();
                while (enumerator.MoveNext())
                {
                    psCommand.Parameters.Add(enumerator.Current.Key, enumerator.Current.Value);
                } 
            }

            pipeline.Commands.Add(psCommand);
            string cmdStr = psCommand.ToString();
            cmdStr = psCommand.CommandText;
            Collection<PSObject> output = pipeline.Invoke();
            string errorMessage = string.Empty;
            if (pipeline.HadErrors)
            {
                errorMessage = pipeline.Error.Read().ToString();
            }
            // pipeline.Invoke(
            runspace.Close();

            if (!string.IsNullOrWhiteSpace(errorMessage))
            {
                throw new Exception(errorMessage);
            }

            return output;
        }
    }
}
